home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / rclesrc.10 / ircle sources / IRCInput.p < prev    next >
Encoding:
Text File  |  1992-09-06  |  7.5 KB  |  348 lines

  1. {    ircle - Internet Relay Chat client    }
  2. {    File: IRCInput    }
  3. {    Copyright ⌐ 1992 Olaf Titz (s_titz@iravcl.ira.uka.de)    }
  4.  
  5. {    This program is free software; you can redistribute it and/or modify    }
  6. {    it under the terms of the GNU General Public License as published by    }
  7. {    the Free Software Foundation; either version 2 of the License, or    }
  8. {    (at your option) any later version.    }
  9.  
  10. {    This program is distributed in the hope that it will be useful,    }
  11. {    but WITHOUT ANY WARRANTY; without even the implied warranty of    }
  12. {    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    }
  13. {    GNU General Public License for more details.    }
  14.  
  15. {    You should have received a copy of the GNU General Public License    }
  16. {    along with this program; if not, write to the Free Software    }
  17. {    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    }
  18.  
  19. unit IRCInput;
  20. { Handles input from the user and sends messages to the server. }
  21. { Handles lines sent from the server. }
  22. { And handles menu commands. }
  23.  
  24. interface
  25. uses
  26.     TCPTypes, TCPStuff, TCPConnections, Coroutines, ApplBase, MsgWindows, InputLine, {}
  27.     IRCGlobals, IRCaux, IRCPreferences, IRCChannels, IRCCommands, DCC, IRCSComm;
  28.  
  29. procedure InitIRCInput;
  30. { Startup }
  31.  
  32. procedure OpenConnection;
  33. { open connection & do autoexec }
  34.  
  35. implementation
  36.  
  37. type
  38.     str20 = string[20];
  39.     CEPtr = ^ConnectionEventRecord;
  40.  
  41. var
  42.     prevcr: boolean;
  43.     ip: longint;
  44.  
  45.  
  46. procedure PasteCommand (s: str20);  { Set the input line to a command }
  47.     begin
  48.         s := concat(cmdchar, s);
  49.         SetInputLine(s);
  50.     end;
  51.  
  52. function MenuFILE (var e: EventRecord): boolean;
  53.     var
  54.         i: integer;
  55.         s: string;
  56.     begin
  57.         MenuFILE := true;
  58.         case loword(e.message) of
  59.             M_F_OPEN: 
  60.                 OpenConnection;
  61.             M_F_CLOSE: 
  62.                 if GetWRefCon(FrontWindow) <> 0 then
  63.                     partWindow(FrontWindow);
  64.             M_F_LOG: 
  65.                 begin
  66.                 if logging then begin
  67.                     close(logfile);
  68.                     logging := false
  69.                 end
  70.                 else begin
  71.                     s := NewFileName('Save log to file:');
  72.                     if s <> '' then begin
  73.                         rewrite(logfile, s);
  74.                         logging := true
  75.                     end
  76.                 end;
  77.             end;
  78.             M_F_FLUSH: 
  79.                 begin
  80.                 flushing := true;
  81.                 UpdateStatusLine
  82.             end;
  83.             M_F_PREFS: 
  84.                 begin
  85.                 ValidPrefs := GetPrefs(true);
  86.                 if ValidPrefs then
  87.                     EnableItem(GetMHandle(M_SHCUTS), 0);
  88.             end;
  89.             M_F_QUIT: 
  90.                 begin
  91.                 if serverStatus = 0 then begin
  92.                     if Alert(A_QUIT, nil) <> 1 then
  93.                         exit(menuFILE);
  94.                     s := 'QUIT';
  95.                     HandleCommand(s);    { try a regular exit }
  96.                 end;
  97.                 ApplExit; { Emergency exit - will give 'bad link' as reason }
  98.             end;
  99.         end;
  100.     end;
  101.  
  102. function MenuCOMMANDS (var e: EventRecord): boolean;
  103.     begin
  104.         case loword(e.message) of
  105.             M_CO_JOIN: 
  106.                 PasteCommand('join ');
  107.             M_CO_PART: 
  108.                 PasteCommand('part ');
  109.             M_CO_LIST: 
  110.                 PasteCommand('list ');
  111.             M_CO_WHO: 
  112.                 PasteCommand('who ');
  113.             M_CO_QUERY: 
  114.                 PasteCommand('query ');
  115.             M_CO_WHOIS: 
  116.                 PasteCommand('whois ');
  117.             M_CO_INVITE: 
  118.                 PasteCommand('invite ');
  119.             M_CO_KICK: 
  120.                 PasteCommand('kick ');
  121.             M_CO_AWAY: 
  122.                 PasteCommand('away ');
  123.             M_CO_MSG: 
  124.                 PasteCommand('msg ');
  125.         end;
  126.         MenuCOMMANDS := true
  127.     end;
  128.  
  129.  
  130. function MenuSHCUTS (var e: EventRecord): boolean;
  131.     var
  132.         s: string;
  133.     begin
  134.         if e.message = M_SH_DEFINE then
  135.             GetShortcuts
  136.         else begin
  137.             s := Shortcuts^^[loword(e.message) - M_SH_FIRST];
  138.             if s <> '' then
  139.                 InsertInputLine(s);
  140.         end;
  141.         MenuSHCUTS := true
  142.     end;
  143.  
  144. function MenuFONTS (var e: EventRecord): boolean;
  145.     var
  146.         s: Str255;
  147.         p0: GrafPtr;
  148.         m: MenuHandle;
  149.         i: integer;
  150.     begin
  151.         m := GetMHandle(262);
  152.         case loword(e.message) of
  153.             M_FO_9: 
  154.                 MWDefaultSize := 9;
  155.             M_FO_10: 
  156.                 MWDefaultSize := 10;
  157.             M_FO_12: 
  158.                 MWDefaultSize := 12;
  159.             M_FO_14: 
  160.                 MWDefaultSize := 14;
  161.             otherwise
  162.                 begin
  163.                 GetItem(m, LoWord(e.message), s);
  164.                 GetFNum(s, MWDefaultFont);
  165.             end
  166.         end;
  167.         if e.message < 5 then
  168.             for i := 1 to 4 do
  169.                 CheckItem(m, i, (i = Loword(e.message)))
  170.         else
  171.             for i := 6 to CountMItems(m) do
  172.                 CheckItem(m, i, (i = Loword(e.message)));
  173.         if MWActive <> nil then begin
  174.             GetPort(p0);
  175.             SetPort(MWActive^^.w);
  176.             SetFontSize(MWActive, MWDefaultFont, MWDefaultSize);
  177.             SetPort(p0)
  178.         end;
  179.         MenuFONTS := true;
  180.     end;
  181.  
  182. { Process a typed line as message. }
  183. { This means: convert it to a PRIVMSG command to the current target, }
  184. { i.e. the channel or query of the active window. }
  185. procedure HandleMessage (var s: string);
  186.     var
  187.         c: string;
  188.     begin
  189.         if currentTarget = '' then
  190.             StatusMsg(E_NOTARGET)
  191.         else if CurrentTarget[1] = DCC_CHAT_PREFIX then
  192.             DCCChatSend(s)
  193.         else begin
  194.             c := concat('PRIVMSG ', CurrentTarget, ' :', s);
  195.             HandleCommand(c);
  196.             c := concat('> ', s);
  197.             Message(c);
  198.             s := '';
  199.         end;
  200.     end;
  201.  
  202. { 'srvHandler' handles lines received from server }
  203. procedure srvHandler (var s: string; cr: boolean);
  204.     begin
  205.         if s[0] <> chr(0) then
  206.             if prevcr then
  207.                 ServerCommands(s)
  208.             else
  209.                 MWMessage(lastwindow, s);
  210.         prevcr := cr;
  211.     end;
  212.  
  213. { 'InputHandler' process handles input from the user }
  214. procedure InputHandler (var s: string);
  215.     begin
  216.         GetDateTime(idleTime);
  217.         if s[0] <> chr(0) then
  218.             if serverStatus = S_CONN then
  219.                 if s[1] = CmdChar then
  220.                     HandleCommand(s)
  221.                 else
  222.                     HandleMessage(s);
  223.     end;
  224.  
  225. function watchFound (var e: EventRecord): boolean;
  226.     var
  227.         c: CEPtr;
  228.     begin
  229.         c := CEPtr(e.message);
  230.         if c^.connection <> sSocket then begin
  231.             watchFound := false;
  232.             exit(watchFound)
  233.         end
  234.         else
  235.             watchFound := true;
  236.         if c^.event = C_Found then
  237.             ip := c^.value
  238.         else if c^.event = C_SearchFailed then
  239.             ip := -1
  240.         else
  241.             watchFound := false
  242.     end;
  243.  
  244. function watchOpen (var e: EventRecord): boolean;
  245.     var
  246.         c: CEPtr;
  247.     begin
  248.         c := CEPtr(e.message);
  249.         if c^.connection <> sSocket then begin
  250.             watchOpen := false;
  251.             exit(watchOpen)
  252.         end
  253.         else
  254.             watchOpen := true;
  255.         if c^.event = C_Established then
  256.             ip := 0
  257.         else if c^.event = C_FailedToOpen then
  258.             ip := -1
  259.         else
  260.             watchOpen := false
  261.     end;
  262.  
  263. function watchLine (var e: EventRecord): boolean;
  264.     var
  265.         c: CEPtr;
  266.         s: string;
  267.         nn: longint;
  268.         i, j: integer;
  269.         cr: boolean;
  270.     begin
  271.         c := CEPtr(e.message);
  272.         if c^.connection = sSocket then begin
  273.             nn := 1;
  274.             i := TCPReceiveUpTo(c^.tcpc, 10, readTimeout, @s[0], 250, nn, cr);
  275.             j := nn - 1;
  276.             while (j > 0) and (s[j] in [chr(10), chr(13)]) do
  277.                 j := pred(j);
  278.             s[0] := chr(j);
  279.             for i := 1 to j do
  280.                 s[i] := ISODecode^^[s[i]];
  281.             srvHandler(s, cr);
  282.             watchLine := true
  283.         end
  284.         else
  285.             watchLine := false;
  286.     end;
  287.  
  288. procedure OpenConnection;
  289.     var
  290.         e: integer;
  291.     begin
  292.         if not validPrefs then
  293.             validPrefs := GetPrefs(true);
  294.         if validPrefs and (serverStatus <> 0) then begin
  295.             CurrentNick := default^^.Nick;
  296.             SetMainTitle(CurrentNick);
  297.             serverStatus := S_LOOKUP;
  298.             UpdateStatusLine;
  299.             SetCursor(Watch^^);
  300.             e := FindAddress(sSocket, default^^.server, nil);
  301.             if e = 0 then begin
  302.                 ip := 0;
  303.                 e := ApplTask(@watchFound, TCPMsg);
  304.                 repeat
  305.                     ApplRun
  306.                 until ip <> 0;
  307.                 ApplUNtask(e);
  308.                 if ip <> -1 then begin
  309.                     serverStatus := S_OPENING;
  310.                     UpdateStatusLine;
  311.                     e := NewActiveConnection(sSocket, 8192, ip, default^^.port, nil);
  312.                     if e = 0 then begin
  313.                         e := ApplTask(@watchOpen, TCPMsg);
  314.                         repeat
  315.                             ApplRun
  316.                         until ip = 0;
  317.                         ApplUNtask(e);
  318.                         if ip <> -1 then begin
  319.                             e := 0;
  320.                             serverStatus := S_CONN;
  321.                             RegUser;
  322.                         end
  323.                         else
  324.                             e := ord(C_FailedToOpen);
  325.                     end
  326.                 end
  327.                 else
  328.                     e := ord(C_SearchFailed);
  329.             end
  330.         end;
  331.         InitCursor;
  332.         serverOK(e);
  333.     end;
  334.  
  335.  
  336. procedure InitIRCInput;
  337.     var
  338.         i: integer;
  339.     begin
  340.         OpenInputLine(@InputHandler);
  341.         i := ApplTask(@MenuFILE, menuMsg + fileMenu);
  342.         i := ApplTask(@MenuCOMMANDS, menuMsg + M_COMMANDS);
  343.         i := ApplTask(@MenuSHCUTS, menuMsg + M_SHCUTS);
  344.         i := ApplTask(@MenuFONTS, menuMsg + M_FONT);
  345.         i := ApplTask(@watchLine, TCPMsg);
  346.     end;
  347.  
  348. end.